#!/usr/bin/env python
# -*- coding: utf-8 -*-

import argparse

class MyVersion( argparse.Action ) :
    def __init__(self,
                 option_strings,
                 version=None,
                 dest=argparse.SUPPRESS,
                 default=argparse.SUPPRESS,
                 help="shows program's version number and exits"):
        super(MyVersion, self).__init__(
            option_strings=option_strings,
            dest=dest,
            default=default,
            nargs=0,
            help=help)
        self.version = version

    def __call__( self, parser, namespace, values, option_string=None ) :
        from XmlCppClassGenerator import fullInformation
        print fullInformation()
        exit( 0 )

class MyTranslation( argparse.Action ) :
    def __init__(self,
                 option_strings,
                 version=None,
                 dest=argparse.SUPPRESS,
                 default=argparse.SUPPRESS,
                 help="shows available translations and exits"):
        super(MyTranslation, self).__init__(
            option_strings=option_strings,
            dest=dest,
            default=default,
            nargs=0,
            help=help)
    def __call__( self, parser, namespace, values, option_string=None ) :
        from XmlCppClassGenerator.Translator import Translator
        from XmlCppClassGenerator import fullInformation
        print fullInformation()
        print ""
        translator = Translator()
        listOfLanguages = translator.getAvailableLanguages()
        print "Available translations:"
        for language in listOfLanguages :
            print "-", language[ 'code' ],
            print u"(" + language[ 'native' ] + u")"
        exit( 0 )
        

parser = argparse.ArgumentParser( description="""Generates C++ classes from
 a class description read from a XML file.""",
                                  epilog="""See https://code.google.com/p/xml-cpp-class-generator/ of more details.
""",
                                  formatter_class=argparse.ArgumentDefaultsHelpFormatter )
parser.add_argument( '-v', '--version', action=MyVersion )
parser.add_argument( type=str, metavar='F', nargs='+',
                     help='XML file(s) to be read',
                     dest='files' )
parser.add_argument( '-H', '--header', type=str, nargs=1,
                     help="""extension for header files""", default='.hpp',
                     action='store', dest='headerExt' )
parser.add_argument( '-I', '--impl', type=str, nargs=1,
                     help="""extension for implementation files""",
                     default='.cpp', action='store', dest='implExt' )
parser.add_argument( '-d', '--directory', type=str,
                     help="destination directory", default='./',
                     action='store', dest='outputDir' )
parser.add_argument( '-l', '--language', type=str, default='en',
                     help="sets the output language", action='store',
                     dest='lang' )
parser.add_argument( '-t', '--translation', action=MyTranslation )
parser.add_argument( '-n', '--noout', action='store_true', default=False,
                     dest='disableOutput', help="""disables the file
 production, will just check syntax""" )
parser.add_argument( '-1', '--level1', type=int, default=3,
                     help="sets output level for the interpretor class",
                     action='store', dest='level1' )
parser.add_argument( '-2', '--level2', type=int, default=3,
                     help="sets output level for the main script",
                     action='store', dest='level2' )

args = parser.parse_args()

from XmlCppClassGenerator import restoreUtf8

restoreUtf8()

from XmlCppClassGenerator import *
from XmlCppClassGenerator import fullPath

translator = Translator.Translator( args.lang )

printer = OutputStreams.OutputStream( args.level2 )

printer.debug( "List of files                 : " + str( args.files ) )
printer.debug( "Header file extention         : " + str( args.headerExt ) )
printer.debug( "Implementation file extention : " + str( args.implExt ) )
printer.debug( "Output directory              : " + str( args.outputDir ) )
printer.debug( "Used language                 : " + str( args.lang ) )
printer.debug( "OutputLevel for interpretor   : " + str( args.level1 ) )
printer.debug( "OuputLevel for the script     : " + str( args.level2 ) )

myInterpretor = Interpretor.Interpretor()
myInterpretor.setOutputLevel( args.level1 )

myInterpretor.setTranslator( translator )

if ( args.disableOutput ) :
    message = translator.getInformationMessage( 'nooutput' )[0]
    printer.info( message )

import subprocess

for file in args.files :
    message = translator.getInformationMessage( 'processing' )[0]

    command = [ 'xmllint', '--noout', '--schema',
                fullPath() + 'XmlCppClassGenerator.xsd', file ]
    check = subprocess.Popen( command, stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE )
    status = check.wait()
    
    if ( status != 0 ) :
        message = translator.getInformationMessage( 'validationError' )[0]
        message = message.replace( '\\n', '\n' )
        printer.error( message.format( file ) )
        for line in check.stderr.readlines() :
            printer.warning( line[:-1] )
        continue

    printer.info( message.format( file ) )

    myInterpretor.setXmlFileName( file )

    myInterpretor.loadDomTree()

    myInterpretor.findClasses()

    if ( args.disableOutput ) : continue

    myInterpretor.writeHeaderFile( args.outputDir )

    myInterpretor.writeImplementationFile( args.outputDir )
